package com.example.leetcode.trainingcamp.week3.Sunday;

import java.util.Stack;

/**
 * 给定一个包含正整数、加(+)、减(-)、乘(*)、除(/)的算数表达式(括号除外)，计算其结果。
 *
 * <p>表达式仅包含非负整数，+， - ，*，/ 四种运算符和空格  。 整数除法仅保留整数部分。
 *
 * <p>来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/calculator-lcci
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class Offer16_26 {

  public int calculate(String s) {
    int length = s.length(); // 计算出字符串s的长度
    int i = 0;
    Stack<Integer> nums = new Stack<>(); // 存放数字的栈
    Stack<Character> ops = new Stack<>(); // 存放 + - * / 的运算符栈
    while (i < length) {
      // 准备遍历字符串
      char c = s.charAt(i);
      if (c == ' ') {
        // 说明为空格，不予处理
        i++;
        continue;
      }
      if (isNumber(c)) {
        int number = c - '0';
        for (i = i + 1; i < length; i++) {
          char c1 = s.charAt(i);
          if (isNumber(c1)) {
            number = number * 10 + (c1 - '0');
          } else {
            break;
          }
        }
        nums.push(number);
        continue;
      }
      if (ops.isEmpty()) {
        // 说明操作符栈为空直接加进去即可
        ops.push(c);
        i++;
      } else {
        while (!ops.isEmpty()) {
          Character peek = ops.peek(); // 查看操作运算符的栈顶是什么运算符
          boolean priority = priority(peek, c);
          if (priority) {
            cal(nums, ops);
          } else {
            ops.push(c);
            i++;
            break;
          }
        }
      }
    }
    while (!ops.isEmpty()) {
      cal(nums, ops);
    }
    return nums.pop();
  }

  public boolean isNumber(char c) {
    return c >= '0' && c <= '9';
  }

  public boolean priority(char c1, char c2) {
    if (c1 == '*' || c1 == '/') {
      return true;
    }
    if ((c1 == '+' || c1 == '-') && (c2 == '+' || c2 == '-')) {
      return true;
    }
    return false;
  }

  public void cal(Stack<Integer> nums, Stack<Character> ops) {
    int nums1 = nums.pop();
    System.out.println("nums1 =" + nums1);
    int nums2 = nums.pop();
    char c = ops.pop();
    int calculate = calculate(nums1, nums2, c);
    nums.push(calculate);
  }

  public int calculate(int nums1, int nums2, char op) {
    int result;
    switch (op) {
      case '+':
        result = nums2 + nums1;
        break;
      case '*':
        result = nums2 * nums1;
        break;
      case '-':
        result = nums2 - nums1;
        break;
      case '/':
        result = nums2 / nums1;
        break;
      default:
        throw new IllegalStateException("Unexpected value: " + op);
    }
    return result;
  }
}

class TestOffer16_26 {
  public static void main(String[] args) {
    Offer16_26 o = new Offer16_26();
    String s = "42";
    System.out.println("result:" + o.calculate(s));
  }
}
